/**
 * Copyright(c) 2022 GOING INTERNATIONAL高盈国际
 * All Rights Reserved
 * @File        : swag.go
 * @Author      : zybin.zou
 * @Create      : 2022/6/29 18:35
 * @Modified    : 2022/6/29 18:35
 * @version     : 1.0
 * @Description :
 */

package swag

/*
#include <stdint.h>

extern uintptr_t NewSumObject();
extern int CSumAdd(uintptr_t object,int a, int b);
extern void CSumRegSpi(uintptr_t object, int spi);
*/
import "C"
import (
	"fmt"
	"sync"
)

var swigDirectorTrack struct {
	sync.Mutex
	m map[int]interface{}
	c int
}

func swigDirectorAdd(v interface{}) int {
	swigDirectorTrack.Lock()
	defer swigDirectorTrack.Unlock()
	if swigDirectorTrack.m == nil {
		swigDirectorTrack.m = make(map[int]interface{})
	}
	swigDirectorTrack.c++
	ret := swigDirectorTrack.c
	swigDirectorTrack.m[ret] = v
	return ret
}

func swigDirectorLookup(c int) interface{} {
	swigDirectorTrack.Lock()
	defer swigDirectorTrack.Unlock()
	ret := swigDirectorTrack.m[c]
	if ret == nil {
		panic("C++ director pointer not found (possible	use-after-free)")
	}
	return ret
}

type ISum interface {
	Add(a, b int) int
	RegSpi(spi interface{})
}

type ISpi interface {
	UintPtr() uintptr
	OnResult(retCode int)
}

type CSum uintptr

func NewCSum() ISum {
	ret := (ISum)(CSum(C.NewSumObject()))
	return ret
}

func (r CSum) Add(a, b int) int {
	ret := int(C.CSumAdd(C.uintptr_t(r), C.int(a), C.int(b)))
	return ret
}

func (r CSum) RegSpi(spi interface{}) {
	C.CSumRegSpi(C.uintptr_t(r), C.int(swigDirectorAdd(spi)))
}

type IOnResult interface {
	OnResult(retCode int)
}

//export GoOnResult
func GoOnResult(goPtr int, retCode int) {
	fmt.Println("export, retCode:", retCode)
	d := swigDirectorLookup(goPtr)
	if v, ok := d.(IOnResult); ok {
		v.OnResult(retCode)
	}
}
